﻿using System.Threading;
using System.Collections;
namespace System.Web
{
    public partial class NetHttpApplication
    {
        internal class AsyncEventExecutionStep : IExecutionStep
        {
            private NetHttpApplication _application;
            private BeginEventHandler _beginHandler;
            private AsyncCallback _completionCallback;
            private EndEventHandler _endHandler;
            private object _state;
            private bool _sync;
            private string _targetTypeStr;

            internal AsyncEventExecutionStep(NetHttpApplication app, BeginEventHandler beginHandler, EndEventHandler endHandler, object state)
            {
                _application = app;
                _beginHandler = beginHandler;
                _endHandler = endHandler;
                _state = state;
                _completionCallback = new AsyncCallback(OnAsyncEventCompletion);
            }

            private void OnAsyncEventCompletion(IAsyncResult ar)
            {
                if (!ar.CompletedSynchronously)
                {
                    var context = _application.Context;
                    Exception error = null;
                    try { _endHandler(ar); }
                    catch (Exception exception2) { error = exception2; }
                    context.WorkerRequest.SetStartTime();
                    ResumeSteps(error);
                }
            }

            private void ResumeSteps(Exception error)
            {
                _application.ResumeStepsFromThreadPoolThread(error);
            }

            void IExecutionStep.Execute()
            {
                _sync = false;
                var ar = _beginHandler(_application, _application.AppEvent, _completionCallback, _state);
                if (ar.CompletedSynchronously)
                {
                    _sync = true;
                    _endHandler(ar);
                }
            }

            bool IExecutionStep.CompletedSynchronously
            {
                get { return _sync; }
            }

            bool IExecutionStep.IsCancellable
            {
                get { return false; }
            }
        }
    }
}